package com.sc.nft.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.ExpenditureRecordDao;
import com.sc.nft.dao.OrderDao;
import com.sc.nft.entity.ExpenditureRecord;
import com.sc.nft.entity.Order;
import com.sc.nft.entity.vo.ExpenditureRecordVO;
import com.sc.nft.entity.vo.MerchantViewBillVO;
import com.sc.nft.enums.ExpenditureRecordTypeEnum;
import com.sc.nft.service.ExpenditureRecordService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 服务接口实现
 *
 * @author Sun
 * @description 由 Mybatisplus Code Generator 创建
 * @since 2022-09-07 12:59:34
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ExpenditureRecordServiceImpl implements ExpenditureRecordService {

    private final ExpenditureRecordDao expenditureRecordDao;
    private final OrderDao orderDao;

    @Override
    public void insertRecord(Long userId, BigDecimal amount, BigDecimal charge, BigDecimal realAmount, ExpenditureRecordTypeEnum type, BigDecimal beforeBalance, BigDecimal afterBalance, Long orderId, String remark) {
        ExpenditureRecord expenditureRecord = new ExpenditureRecord();
        expenditureRecord.setUserId(userId);
        expenditureRecord.setAmount(amount);
        expenditureRecord.setCharge(charge);
        expenditureRecord.setRealAmount(realAmount);
        expenditureRecord.setType(type);
        expenditureRecord.setBeforeBalance(beforeBalance);
        expenditureRecord.setAfterBalance(afterBalance);
        expenditureRecord.setOrderId(orderId);
        expenditureRecord.setRemark(remark);
        expenditureRecordDao.insert(expenditureRecord);
    }

    /**
     * 填充 #firstTitle 字段
     *
     * @param list             填充实体列表
     * @param orderIdGetter    #orderId 获取函数
     * @param firstTitleSetter #firstTitle 设置函数
     * @param <T>              实体类型
     */
    private <T> void fillFirstTitle(List<T> list, Function<T, Long> orderIdGetter, BiConsumer<T, String> firstTitleSetter) {
        List<Long> orderIds = list.stream()
                .map(orderIdGetter)
                .filter(Objects::nonNull)
                .filter(orderId -> orderId > 0)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(orderIds)) {
            list.forEach(item -> firstTitleSetter.accept(item, ""));
            return;
        }

        List<Order> orders = orderDao.listByIds(orderIds);
        if (CollectionUtils.isEmpty(orders)) {
            list.forEach(item -> firstTitleSetter.accept(item, ""));
            return;
        }

        final Map<Long, String> map = orders.stream().collect(Collectors.toMap(Order::getId, Order::getFirstTitle));
        list.forEach(item -> firstTitleSetter.accept(item, map.getOrDefault(orderIdGetter.apply(item), "")));
    }

    @Override
    public Page<ExpenditureRecordVO> getExpenditureRecord(Long userId, String calendar, Integer pageNo, Integer pageSize, Integer type) {
        Page<ExpenditureRecordVO> page = expenditureRecordDao.getExpenditureRecord(userId, calendar, pageNo, pageSize, type);
        List<ExpenditureRecordVO> records = page.getRecords();
        // 消除与订单表的关联查询，这里填充 firstTitle 字段信息
        fillFirstTitle(records, ExpenditureRecordVO::getOrderId, ExpenditureRecordVO::setFirstTitle);
        for (ExpenditureRecordVO expenditureRecordVO : records) {
            expenditureRecordVO.setIsAdd(expenditureRecordVO.getType().isAdd());
            String remark = expenditureRecordVO.getRemark();
            remark = remark == null ? "" : remark;
            expenditureRecordVO.setFirstTitle(remark); // @WangWeiCheng 确认保留 first_title 字段查询逻辑，不再重新赋值
            expenditureRecordVO.setTypeName(expenditureRecordVO.getType().getDescription());
            expenditureRecordVO.setImageUrl(expenditureRecordVO.getType().getImageUrl());
        }
        return page;
    }

    @Override
    public Page<MerchantViewBillVO> merchantViewBill(Long userId, Date startTime, Date endTime, Integer pageNo, Integer pageSize, ExpenditureRecordTypeEnum type) {
        Page<MerchantViewBillVO> page = expenditureRecordDao.merchantViewBill(userId, startTime, endTime, pageNo, pageSize, type);
        List<MerchantViewBillVO> records = page.getRecords();
        // 消除与订单表的关联查询，这里填充 firstTitle 字段信息
        fillFirstTitle(records, MerchantViewBillVO::getOrderId, MerchantViewBillVO::setFirstTitle);
        for (MerchantViewBillVO expenditureRecordVO : records) {
            expenditureRecordVO.setIsAdd(expenditureRecordVO.getType().isAdd());
//            String remark = expenditureRecordVO.getRemark();
//            remark = remark ==null ? "":remark;
//            expenditureRecordVO.setFirstTitle(remark); // @WangWeiCheng 确认保留 first_title 字段查询逻辑，不再重新赋值
            expenditureRecordVO.setTypeName(expenditureRecordVO.getType().getDescription());
            expenditureRecordVO.setImageUrl(expenditureRecordVO.getType().getImageUrl());
        }
        return page;
    }
}